//! `std::sync` 模块的测试用例
//!
//! 本文件包含对 `std::sync` 中同步原语的测试，
//! 包括 `Arc`, `Mutex`, `RwLock`, `Condvar`, `Barrier`, 和 `mpsc` (多生产者单消费者) 通道。

#[cfg(test)]
mod tests {
    use std::sync::mpsc::{self, Receiver, Sender};
    use std::sync::{Arc, Barrier, Condvar, Mutex, RwLock};
    use std::thread;
    use std::time::Duration;

    // --- Arc (原子引用计数) ---
    #[test]
    fn test_arc() {
        let data = Arc::new(vec![1, 2, 3]);
        let mut handles = vec![];

        for i in 0..3 {
            let data_clone = Arc::clone(&data);
            let handle = thread::spawn(move || {
                // 每个线程都可以访问共享数据
                assert_eq!(data_clone[i], i as i32 + 1);
            });
            handles.push(handle);
        }

        for handle in handles {
            handle.join().unwrap();
        }
        // 检查 Arc 的强引用计数
        assert_eq!(Arc::strong_count(&data), 1);
    }

    // --- Mutex (互斥锁) ---
    #[test]
    fn test_mutex() {
        let counter = Arc::new(Mutex::new(0));
        let mut handles = vec![];

        for _ in 0..10 {
            let counter_clone = Arc::clone(&counter);
            let handle = thread::spawn(move || {
                let mut num = counter_clone.lock().unwrap();
                *num += 1;
            });
            handles.push(handle);
        }

        for handle in handles {
            handle.join().unwrap();
        }

        assert_eq!(*counter.lock().unwrap(), 10);
    }

    // --- RwLock (读写锁) ---
    #[test]
    fn test_rwlock() {
        let lock = Arc::new(RwLock::new(5));
        let mut handles = vec![];

        // 多个读线程
        for _ in 0..5 {
            let lock_clone = Arc::clone(&lock);
            let handle = thread::spawn(move || {
                let val = lock_clone.read().unwrap();
                assert_eq!(*val, 5);
                thread::sleep(Duration::from_millis(10));
            });
            handles.push(handle);
        }

        // 一个写线程
        let lock_clone = Arc::clone(&lock);
        let write_handle = thread::spawn(move || {
            thread::sleep(Duration::from_millis(5)); // 等待读线程先获取锁
            let mut val = lock_clone.write().unwrap();
            *val = 10;
        });
        handles.push(write_handle);

        for handle in handles {
            handle.join().unwrap();
        }

        assert_eq!(*lock.read().unwrap(), 10);
    }

    // --- Condvar (条件变量) ---
    #[test]
    fn test_condvar() {
        let pair = Arc::new((Mutex::new(false), Condvar::new()));
        let pair2 = Arc::clone(&pair);

        let handle = thread::spawn(move || {
            let (lock, cvar) = &*pair2;
            let mut started = lock.lock().unwrap();
            // 等待主线程的通知
            while !*started {
                started = cvar.wait(started).unwrap();
            }
            assert_eq!(*started, true);
        });

        thread::sleep(Duration::from_millis(20));
        let (lock, cvar) = &*pair;
        let mut started = lock.lock().unwrap();
        *started = true;
        // 通知等待的线程
        cvar.notify_one();
        drop(started); // 释放锁

        handle.join().unwrap();
    }

    // --- Barrier (屏障) ---
    #[test]
    fn test_barrier() {
        let mut handles = Vec::with_capacity(5);
        let barrier = Arc::new(Barrier::new(5));

        for _ in 0..5 {
            let c = Arc::clone(&barrier);
            handles.push(thread::spawn(move || {
                println!("线程 {:?} 到达屏��前", thread::current().id());
                c.wait(); // 等待所有线程到达
                println!("线程 {:?} 越过屏障", thread::current().id());
            }));
        }

        for handle in handles {
            handle.join().unwrap();
        }
    }

    // --- mpsc (多生产者，单消费者) 通道 ---
    #[test]
    fn test_mpsc_channel() {
        let (tx, rx): (Sender<i32>, Receiver<i32>) = mpsc::channel();
        let mut handles = vec![];

        // 创建多个生产者
        for i in 0..5 {
            let tx_clone = tx.clone();
            let handle = thread::spawn(move || {
                tx_clone.send(i).unwrap();
            });
            handles.push(handle);
        }
        drop(tx); // 关闭主发送者，这样接收者才能知道没有更多消息了

        for handle in handles {
            handle.join().unwrap();
        }

        let mut received_values = vec![];
        for received in rx {
            received_values.push(received);
        }

        received_values.sort();
        assert_eq!(received_values, vec![0, 1, 2, 3, 4]);
    }
}
